home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / EMBL Search / Sources / export.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-04  |  17.3 KB  |  732 lines  |  [TEXT/KAHL]

  1. /*
  2. *********************************************************************
  3. *    
  4. *    Export.c
  5. *    Export of database entries
  6. *
  7. *    Rainer Fuchs
  8. *    EMBL Data Library
  9. *    Postfach 10.2209
  10. *    D-6900 Heidelberg, FRG
  11. *    E-mail: fuchs@embl-heidelberg.de
  12. *
  13. *    Copyright © 1992 EMBL Data Library
  14. *        
  15. **********************************************************************
  16. *    
  17. */ 
  18.  
  19. #include <string.h>
  20. #include <stdio.h>
  21. #include <Notification.h>
  22.  
  23. #include "EMBL-Search.h"
  24. #include "EMBL-Search.rsrc.h"
  25.  
  26. /*
  27. ******************************* Prototypes ***************************
  28. */
  29.  
  30. #include "export.h"
  31. #include "util.h"
  32. #include "hitstorage.h"
  33. #include "window.h"
  34. #include "pstr.h"
  35. #include "events.h"
  36.  
  37. static Boolean Export1(HitlistHdl hlHdl, short pos, short output, short dbcode, StringPtr outFName, char *inpBuf, char *outBuf, DialogPtr myDialog);
  38. static Boolean WriteEMBLEntry(char *inpBuf, char *outBuf, short output, StringPtr outFName, long count);
  39. static Boolean WriteSeqOnly(char *inpBuf, char *outBuf, short output, StringPtr outFName, long count);
  40. static short GetExportFilename(StringPtr oldFName, short *vRefNum, StringPtr newFName);
  41. static pascal short myExportDlgHook(short theItem, DialogPtr myDialog);
  42. static Boolean UserBreak(DialogPtr myDialog);
  43. static void WaitUntilForeground(void);
  44. static void NotifyUser(NMRec *myNMPtr);
  45. static pascal void NotifyResponse(NMRec *myNMPtr);
  46. static void RemoveNotification(NMRec *myNMPtr);
  47.  
  48.  
  49.  
  50. /*
  51. ********************************* Globals *****************************
  52. */
  53.  
  54. extern Prefs         gPrefs;
  55. extern DBInfo        gDBInfo[DB_NUM];
  56. extern IndexFiles    gFileList;
  57. extern char            gError[256];
  58. extern short        gSysVersion;
  59. extern Boolean        gInBackground;
  60. extern Rect            gDragRect;
  61. extern MenuHandle    gMenu[MENUNR];
  62.  
  63. static Boolean lbSkipButton,lbSaveAllButton;
  64.  
  65.  
  66. /**************************************
  67. *    Export entries
  68. */
  69.  
  70. void ExportRes(WDPtr wdp)
  71. {
  72.     ResultHdl        resHdl;
  73.     HitlistHdl        hlHdl;
  74.     CString80Hdl    bufHdl;
  75.     Str255            ename,oldFName,newFName;
  76.     short             vRefNum;
  77.     short                i, found;
  78.     short                output=0;
  79.     SignedByte        oldState;
  80.     Boolean            ret,ret2;
  81.     char                 *inpBuf,*outBuf;
  82.     DialogPtr        myDialog = NULL;
  83.     DialogTHndl        myHandle;
  84.     Boolean            bUserBreak = FALSE, bUserNotified = FALSE;
  85.     NMRec                myNotification;
  86.     
  87.     if( wdp == NULL || ((WindowPeek)wdp)->windowKind != resW )
  88.         return;
  89.         
  90.     resHdl = (ResultHdl)(wdp->userHandle);
  91.     if( !resHdl )
  92.         return;
  93.         
  94.     hlHdl = (**resHdl).hlHdl;
  95.     if( !hlHdl )
  96.         return;
  97.     oldState = LockHandleHigh((Handle)hlHdl);
  98.     
  99.     bufHdl = (**resHdl).descBufHdl;
  100.     
  101.     /* Allocate file buffers */
  102.     inpBuf=NewPtr((Size)FILEBUF);
  103.     if(inpBuf)
  104.         if( !(outBuf=NewPtr((Size)FILEBUF)) )
  105.             DisposPtr((Ptr)inpBuf);
  106.     if ( !inpBuf || !outBuf ) {
  107.         HSetState((Handle)hlHdl,oldState);
  108.         ErrorMsg(ERR_MEMORY);
  109.         return;
  110.     }
  111.         
  112.     StartWaitCursor();
  113.     
  114.     /* Loop for all hits */
  115.     for(i=0,found=0,lbSaveAllButton = bUserBreak = FALSE;
  116.          i < (**resHdl).nhits && bUserBreak == FALSE;
  117.          ++i) {
  118.         /* and export those which are selected */
  119.         if( GetSelectState(hlHdl,i) ) {
  120.             if( i < (**resHdl).buftop || i >= (**resHdl).buftop + MAXBUFLINES) {
  121.                 ret2 = FillDEBuffer(resHdl,i,FALSE);
  122.                 if( !ret2 )
  123.                     break;
  124.             }
  125.  
  126.             ret = OK;
  127.             
  128.             ExtractEname(bufHdl,i-(**resHdl).buftop,ename);
  129.             
  130.             /* if necessary, ask user for filename */
  131.             if( lbSaveAllButton == FALSE ) {
  132.                 InitCursor();
  133.                 BuildFName(oldFName,ename,gPrefs.format);
  134.                 ret=GetExportFilename(oldFName,&vRefNum,newFName);
  135.                 if( ret == OK ) {
  136.                     if( CreateMacFile(newFName,vRefNum,
  137.                                 gPrefs.creatorSig,kSeqFileType,TRUE) != noErr )
  138.                         break;
  139.                     if( OpenMacFile(newFName,vRefNum, &output, TRUE) != noErr)
  140.                         break;
  141.                 }
  142.             }
  143.             
  144.             /* check whether user cancelled or wants to skip an entry */
  145.             if( ret == Cancel ) {
  146.                 if(lbSkipButton)
  147.                     continue;
  148.                 else
  149.                     break;
  150.             }
  151.             else {
  152.                 RotateWaitCursor();
  153.                 
  154.                 if(myDialog == NULL) {
  155.                     if(gSysVersion >= 0x0700) {
  156.                         myHandle = (DialogTHndl)GetResource('DLOG',EXPORT_DLG);
  157.                         (**myHandle).procID = movableDBoxProc;
  158.                     }
  159.                     CenterDA('DLOG',EXPORT_DLG,50);
  160.                     myDialog = GetNewDialog(EXPORT_DLG,NULL,(WindowPtr) -1);
  161.                     DisableMenuBar();
  162.                 }
  163.                 
  164.                 ParamText(ename,"\p","\p","\p");
  165.                 ShowWindow(myDialog);
  166.                 DrawDialog(myDialog);
  167.                 if(UserBreak(myDialog))
  168.                     bUserBreak = TRUE;
  169.                 else {
  170.                     /* copy entry to disk */
  171.                     if( !Export1(hlHdl,i,output,(**resHdl).dbcode,
  172.                                     newFName,inpBuf,outBuf,myDialog) )
  173.                         break;
  174.                                     
  175.                     ++found;
  176.                     if( found > (**resHdl).nsel )
  177.                         break;
  178.                         
  179.                     /* close file if necessary */
  180.                     if( lbSaveAllButton == FALSE ) {
  181.                         FSClose(output);
  182.                         output = 0;
  183.                     }
  184.                     
  185.                     if(lbSaveAllButton == FALSE) {
  186.                         DisposDialog(myDialog);
  187.                         myDialog = NULL;
  188.                     }
  189.                 }
  190.             }
  191.         }
  192.     }
  193.     
  194.     if(myDialog) DisposDialog(myDialog);
  195.     if (output) FSClose(output);
  196.     FlushVol(NULL,vRefNum);
  197.     HSetState((Handle)hlHdl,oldState);
  198.     DisposPtr((Ptr)inpBuf);
  199.     DisposPtr((Ptr)outBuf);
  200.     EnableMenuBar();
  201.     InitCursor();
  202.     
  203.     /* if we were switched to background we notify user of completion */
  204.     if (gInBackground) {
  205.         bUserNotified = TRUE;
  206.         NotifyUser(&myNotification);
  207.     }
  208.     else
  209.         bUserNotified = FALSE;
  210.         
  211.     /* wait till we're activated */
  212.     WaitUntilForeground();
  213.     
  214.     /* remove notification */
  215.     if(bUserNotified == TRUE)
  216.         RemoveNotification(&myNotification);
  217. }
  218.  
  219. /**************************************
  220. *    Look up entries in entryname index for export, and call Export2 to actually
  221. *    do the job
  222. *    Return value:    TRUE, if successful
  223. *                        FALSE, if error occurred
  224. */
  225.  
  226. static Boolean Export1(HitlistHdl hlHdl, short pos,short output,short dbcode,
  227.                         StringPtr outFName, char *inpBuf,char *outBuf,DialogPtr myDialog)
  228. {
  229.     OSErr        err;
  230.     short        input;
  231.     long        size,count;
  232.     u_long    rec;
  233.     EnameRec    enameRec;
  234.     Str255    indexFName,divFName;
  235.     Boolean    ret;
  236.     
  237.     /* Open entryname index  */
  238.     pstrcpy(indexFName,gFileList.enameIdxFName);
  239.     if( OpenMacFileReadOnly(indexFName,gDBInfo[dbcode].InxWDRefNum,&input, TRUE) != noErr )
  240.         return(FALSE);
  241.     
  242.     /* goto appropriate position */
  243.     size = sizeof(EnameRec);
  244.     rec = (*hlHdl)[pos].ename_rec;
  245.     
  246.     if( (err=SetFPos(input,fsFromStart,rec*size + sizeof(Header))) != noErr) {
  247.         sprintf(gError,LoadErrorStr(ERR_READFILE,FALSE),
  248.                     PtoCstr(indexFName),err );
  249.         FSClose(input);
  250.         return(ErrorMsg(0));
  251.     }
  252.  
  253.     /* read record */
  254.     count=size;
  255.     if( ReadMacFile(input,&count,&enameRec,indexFName,TRUE) ) {
  256.         FSClose(input);
  257.         return(FALSE);
  258.     }
  259.     else
  260.         FSClose(input);
  261.     
  262.     /* convert values */
  263.     ConvertLong(&enameRec.annotation_offset);
  264.     ConvertLong(&enameRec.sequence_offset);
  265.     ConvertShort(&enameRec.div_code);
  266.     
  267.     /* Store data file name */    
  268.     pstrcpy(divFName,
  269.         (StringPtr)(*gDBInfo[dbcode].gDivNames + (enameRec.div_code)*(DIVNAMELEN+1)));
  270.     
  271.     /* Open sequence data file */
  272.     if(OpenMacFileReadOnly(divFName,gDBInfo[dbcode].SeqWDRefNum,&input,TRUE) != noErr )
  273.         return(FALSE);
  274.     
  275.     ret=Export2(input,enameRec.annotation_offset,enameRec.sequence_offset,dbcode,
  276.                     divFName,inpBuf,outBuf,output,outFName,myDialog);
  277.     FSClose(input);
  278.     
  279.     if(!ret)
  280.         return(FALSE);
  281.     else {
  282.         count=1;
  283.         WriteMacFile(output,&count,"\r",outFName, TRUE);
  284.         return(TRUE);
  285.     }
  286. }
  287.  
  288.  
  289. /**************************************
  290. *    Read a sequence from database and write it to a file
  291. *    Return value:    TRUE, if successful
  292. *                        FALSE, if error occurred
  293. */
  294.  
  295. Boolean Export2(short input,long ann_offset,long seq_offset,short dbcode,StringPtr fName,
  296.                 char *inpBuf,char *outBuf,short output,StringPtr outFName,
  297.                 DialogPtr myDialog)
  298. {
  299.     OSErr        err;
  300.     Boolean    bDone;
  301.     long        count;
  302.     short        i;
  303.     char        ename[ENTRYNAMELEN+1];
  304.     char        *pos;
  305.     long        offset;
  306.     char        c;
  307.     
  308. #define _MAXDESCLEN    60
  309.     char description[_MAXDESCLEN+1];
  310.     
  311.     /* Go to entry in database */
  312.     offset = (gPrefs.format == STADEN_FORMAT) ? seq_offset : ann_offset;
  313.     if( (err=SetFPos(input,fsFromStart,offset)) != noErr) {
  314.         sprintf(gError,LoadErrorStr(ERR_READFILE,FALSE),PtoCstr(fName),err );
  315.         CtoPstr((char *)fName);
  316.         return(ErrorMsg(0));
  317.     }
  318.  
  319.     if(gPrefs.format == PIR_FORMAT || gPrefs.format == FASTA_FORMAT) {
  320.         RotateWaitCursor();    /* we're busy */
  321.         
  322.         /* read first block of data */
  323.         count=FILEBUF;
  324.         if( (err=ReadMacFile(input,&count,inpBuf,fName,TRUE)) != noErr && err != eofErr )
  325.             return(FALSE);
  326.         if (!count)
  327.             return(TRUE);    /* or false ?! */
  328.     
  329.         strncpy(ename,inpBuf+5,ENTRYNAMELEN);
  330.         ename[ENTRYNAMELEN]=EOS;
  331.         rtrim(ename);
  332.     
  333.         if ( (pos = strstr(inpBuf,"\nDE   ")) != NULL) {
  334.             for(i=0,pos += 6; *pos != '\r' && i < _MAXDESCLEN; ++i,++pos) 
  335.                 description[i] = *pos;
  336.             description[i] = EOS;
  337.         }
  338.         else *description = EOS;
  339.         
  340.         /* skip to sequence */
  341.         RotateWaitCursor();    /* we're busy */
  342.         if( (err=SetFPos(input,fsFromStart,seq_offset)) != noErr) {
  343.             sprintf(gError,LoadErrorStr(ERR_READFILE,FALSE),PtoCstr(fName),err );
  344.             CtoPstr((char *)fName);
  345.             return(ErrorMsg(0));
  346.         }
  347.         
  348.         if(gPrefs.format == PIR_FORMAT) {
  349.             c = (dbcode == DB_SWISS) ? 'P' : 'D';
  350.             sprintf(outBuf,">%c1;%s\r%s\r",c,ename,description);
  351.         }
  352.         else if (gPrefs.format == FASTA_FORMAT) {
  353.             sprintf(outBuf,">%s - %s\r",ename,description);
  354.         }
  355.         
  356.         count=strlen(outBuf);
  357.         if( WriteMacFile(output,&count,outBuf,outFName, TRUE) )
  358.             return(FALSE);
  359.     }
  360.     
  361.     bDone=FALSE;
  362.     while( !bDone ) {
  363.         RotateWaitCursor();    /* we're busy */
  364.         if(UserBreak(myDialog))
  365.             return(FALSE);
  366.             
  367.         /* read from database */
  368.         count=FILEBUF;
  369.         if( (err=ReadMacFile(input,&count,inpBuf,fName,TRUE)) != noErr && err != eofErr )
  370.             return(FALSE);
  371.         if (!count)
  372.             return(TRUE);    /* or false ?! */
  373.         
  374.         /* write to file. check success ?! */
  375.         switch( gPrefs.format) {
  376.             case EMBL_FORMAT:
  377.                 bDone=WriteEMBLEntry(inpBuf,outBuf,output,outFName,count);
  378.                 break;
  379.             case STADEN_FORMAT:
  380.             case PIR_FORMAT:
  381.             case FASTA_FORMAT:
  382.                 bDone=WriteSeqOnly(inpBuf,outBuf,output,outFName,count);
  383.                 break;
  384.         }
  385.     }
  386.     
  387.     return(TRUE);
  388. }
  389.  
  390. /**************************************
  391. *    Write EMBL format
  392. *    Return value:    TRUE, if successful
  393. *                        FALSE, if error occurred
  394. */
  395.  
  396. static Boolean WriteEMBLEntry(char *inpBuf,char *outBuf,short output,
  397.                                 StringPtr outFName,long count)
  398. {
  399.     static char    lastChar;
  400.     Boolean        foundEnd;
  401.     register        long i,j;
  402.     
  403.     /* We go through the input buffer and copy every character to output buffer,
  404.         skipping over line feeds. If we find a //, we stop. Because it may happen
  405.         that the first / is the last character of one read operation, and the
  406.         second / is the first character of the next read operation, we check
  407.         for this special case
  408.     */
  409.  
  410.     lastChar=EOS;
  411.     for(i=0,j=0,foundEnd=FALSE;i<count;++i) {
  412.         if(inpBuf[i] == '\n')                /* skip over line feeds */
  413.             continue;
  414.                 
  415.         outBuf[j++]=inpBuf[i];                /* move character to output buffer */
  416.         if(inpBuf[i] == '/') {                /* check for end of sequence */
  417.             if(i>0) {                        /* if it's not the first char in buffer */
  418.                 if(inpBuf[i-1] == '/') {    /* check previous character */
  419.                     foundEnd=TRUE;            /* found // */
  420.                     break;
  421.                 }
  422.             }
  423.             else if(lastChar == '(') {        /* if / is the first char in buffer,
  424.                                                             check last character of previous buffer
  425.                                                             contents */
  426.                 foundEnd=TRUE;
  427.                 break;
  428.             }
  429.         }                
  430.     }
  431.     
  432.     count=j;
  433.     if( WriteMacFile(output,&count,outBuf,outFName,TRUE) ) {
  434.         lastChar = EOS;
  435.         return(TRUE);
  436.     }
  437.         
  438.     lastChar=inpBuf[j];
  439.         
  440.     if(foundEnd)
  441.         lastChar=EOS;
  442.         
  443.     return(foundEnd);
  444. }
  445.  
  446. /**************************************
  447. *    Write sequence only to a file
  448. *    Return value:    TRUE, if successful
  449. *                        FALSE, if error occurred
  450. */
  451.  
  452. static Boolean WriteSeqOnly(char *inpBuf,char *outBuf,short output,
  453.                                 StringPtr outFName,long count)
  454. {
  455.     Boolean            foundEnd;
  456.     register long    i,j;
  457.     
  458.     /* We go through the input buffer and copy every character to output buffer,
  459.         skipping over line feeds. If we find a //, we stop. We don't copy the // */
  460.  
  461.     for(i=0,j=0,foundEnd=FALSE;i<count;++i) {
  462.         if(inpBuf[i] == '\n' || inpBuf[i] == ' ')    /* skip over line feeds and blanks */
  463.             continue;
  464.                 
  465.         if(inpBuf[i] == '/') {            /* check for end of sequence */
  466.             /* add * for PIR format */
  467.             if (gPrefs.format == PIR_FORMAT)
  468.                 outBuf[j++] = '*';
  469.                 
  470.             foundEnd=TRUE;            /* found // */
  471.             break;
  472.         }
  473.  
  474.         outBuf[j++]=inpBuf[i];                /* move character to output buffer */
  475.     }
  476.         
  477.     count=j;
  478.     if( WriteMacFile(output,&count,outBuf,outFName,TRUE) )
  479.         return(TRUE);
  480.     return(foundEnd);                
  481. }
  482.  
  483. /**************************************
  484. *    Extracts entryname from short description
  485. *    Return value:    none
  486. *    Side-effect:    Pascal file name in "name"
  487. */
  488.  
  489. void ExtractEname(CString80Hdl bufHdl, short pos, StringPtr ename)
  490. {
  491.     BlockMove((*bufHdl)[pos]+1,ename,ENTRYNAMELEN);
  492.     ename[ENTRYNAMELEN]=EOS;
  493.     rtrim((char *)ename);
  494.     CtoPstr((char *)ename);
  495. }
  496.     
  497.  
  498. /**************************************
  499. *    Construct default file name from entryname
  500. *    Return value:    none
  501. *    Side-effect:    Pascal file name in "filename"
  502. */
  503.  
  504. void BuildFName(StringPtr filename, StringPtr ename, short format)
  505. {
  506.     Str255 extension;
  507.     
  508.     pstrcpy(filename,ename);
  509.     GetIndString(extension,EXTENSIONS_STR,gPrefs.format);
  510.     pstrcat(filename,extension);
  511. }
  512.  
  513. /**************************************
  514. *    Ask user for filename
  515. *    Return value:    Code of selected button
  516. *    Side-effect:    selected file name in "newFName"
  517. */
  518.  
  519. static short GetExportFilename(StringPtr oldFName,short *vRefNum,StringPtr newFName)
  520. {
  521.     SFReply    reply;
  522.     Point        where;
  523.     Str255    prompt;
  524.     
  525.     /* Deactivate current front window. SFPut/GetFile sends an activate event
  526.         when it quits but not when it opens ! */
  527.     HandleActivates(FrontWindow(),0);
  528.     GetIndString(prompt,OTHERS,PROMPTSTR);
  529.     CenterSFDlg(SAVEENTRY_DLG,&where);
  530.     lbSkipButton = FALSE;
  531.     SFPPutFile(where, prompt, oldFName, (ProcPtr)myExportDlgHook,
  532.         &reply,SAVEENTRY_DLG,NULL);
  533.     
  534.     if (reply.good) {
  535.         pstrcpy(newFName,reply.fName);
  536.         *vRefNum = reply.vRefNum;
  537.         return(OK);
  538.     }
  539.     else return(Cancel);
  540. }
  541.  
  542. /**************************************
  543. *    Dialog hook routine to initialise file dialog and to handle skip button
  544. *    Return value:    theItem
  545. */
  546.  
  547. static pascal short myExportDlgHook(short theItem, DialogPtr myDialog)
  548. {
  549.     short        kind;
  550.     Handle    h;
  551.     Rect        r;
  552.     Str255    str;
  553.     
  554.     switch(theItem) {
  555.         /* initialisation of dialog (called first time before dialog is displayed) */
  556.         case -1:
  557.             GetDItem(myDialog,SAVEALL_BUTTON,&kind,&h,&r);
  558.             if(gPrefs.format != STADEN_FORMAT)
  559.                 HiliteControl((ControlHandle)h,ACTIVE);
  560.             else
  561.                 HiliteControl((ControlHandle)h,INACTIVE);
  562.                 
  563.             GetIndString(str,FORMAT_STRINGS,gPrefs.format);
  564.             SetDlgText(myDialog, FORMAT_STR, str);
  565.             break;
  566.             
  567.         case SKIP_BUTTON:
  568.             lbSkipButton = TRUE;
  569.             theItem=putCancel;
  570.             break;
  571.             
  572.         case SAVEALL_BUTTON:
  573.             lbSaveAllButton = TRUE;
  574.             theItem = OK;
  575.             break;
  576.     }
  577.     
  578.     return(theItem);
  579. }
  580.  
  581. /**************************************
  582. *    EventHandling during movable modal dialog
  583. *    Return value: TRUE if user cancelled
  584. */
  585.  
  586. static Boolean UserBreak(DialogPtr myDialog)
  587. {
  588.     EventRecord theEvent;
  589.     DialogPtr    whichDialog;
  590.     short            itemHit;
  591.     WindowPtr    whichWindow;
  592.     static long    ticks = 0;
  593.     
  594.     if(gInBackground || TickCount() - ticks > 30) {
  595.         ticks = TickCount();
  596.         if(WaitNextEvent(everyEvent,&theEvent,
  597.                                 gInBackground ? 25 : 0,NULL)) {
  598.             if(theEvent.what == osEvt) /* see "Zen and..." (bug in IsDialogEvent) */
  599.                 DoEvent(theEvent);
  600.             else if(theEvent.what == keyDown || theEvent.what == autoKey) {
  601.                 if ( CmdPeriod(&theEvent)  ||
  602.                     ( (theEvent.message & keyCodeMask) >> 8 == ESCAPE))
  603.                     return(TRUE);
  604.             }
  605.             else {
  606.                 if(IsDialogEvent(&theEvent)) {
  607.                     if(DialogSelect(&theEvent,&whichDialog,&itemHit))
  608.                         if(whichDialog == myDialog && itemHit == OK)
  609.                             return(TRUE);
  610.                 }
  611.                 else {
  612.                     switch(theEvent.what) {
  613.                         case updateEvt:
  614.                         case activateEvt:
  615.                             DoEvent(theEvent);
  616.                             break;
  617.                         case mouseDown:
  618.                             switch (FindWindow( theEvent.where, &whichWindow )) {
  619.                                 case inSysWindow:
  620.                                     SystemClick( &theEvent, whichWindow );
  621.                                     break;
  622.                                 case inDrag:
  623.                                     if(whichWindow == myDialog)
  624.                                         DragWindow(whichWindow,theEvent.where,&gDragRect);
  625.                                     break;
  626.                                     case inMenuBar:
  627.                                 MenuSelect(theEvent.where);
  628.                                     HiliteMenu(0);
  629.                                     break;
  630.                                 default:
  631.                                     SysBeep(10);
  632.                                     break;
  633.                             }
  634.                             break;
  635.                         default:
  636.                             break;
  637.                     }
  638.                 }
  639.             }
  640.         }
  641.     }
  642.     
  643.     return(FALSE);
  644. }
  645.  
  646. /**************************************
  647. *    Disable menu bar before drawing movable modal dialog
  648. */
  649.  
  650. void DisableMenuBar()
  651. {
  652.     register short i;
  653.     
  654.     HiliteMenu(0);    
  655.     for(i=0;i <= WINDOWS;DisableItem(gMenu[i++],0));
  656.     DrawMenuBar();
  657. }
  658.  
  659. /**************************************
  660. *    reenable menu bar after "movable modal dialog"
  661. */
  662.  
  663. void EnableMenuBar()
  664. {
  665.     register short i;
  666.     
  667.     for(i=0;i <= WINDOWS;EnableItem(gMenu[i++],0));
  668.     DrawMenuBar();
  669. }
  670.  
  671. /**************************************
  672. *    Simply looping until we are switched to foreground
  673. */
  674.  
  675. static void WaitUntilForeground()
  676. {
  677.     EventRecord theEvent;
  678.     
  679.     while(gInBackground) {
  680.         if(WaitNextEvent(everyEvent,&theEvent,0x7FFFFFFF,NULL)) {
  681.             switch (theEvent.what) {
  682.                 case updateEvt:
  683.                 case activateEvt:
  684.                 case osEvt:
  685.                     DoEvent(theEvent);
  686.                     break;
  687.                 default:
  688.                     break;
  689.             }
  690.         }
  691.     }
  692. }
  693.  
  694. /**************************************
  695. *    Install notification record in system queue
  696. */
  697.  
  698. static void NotifyUser(NMRec *myNMPtr)
  699. {
  700.     static Handle myResHdl;        /* we use static because the Handle must be valid
  701.                                             when the notification actually takes place ! */    
  702.     
  703.     myResHdl = GetResource('SICN',128);
  704.     
  705.     myNMPtr->qType = nmType;
  706.     myNMPtr->nmMark = 1;
  707.     myNMPtr->nmIcon = myResHdl;
  708.     myNMPtr->nmSound = (Handle)-1;
  709.     myNMPtr->nmStr = NULL;
  710.     myNMPtr->nmResp = (ProcPtr)NotifyResponse;
  711.     
  712.     NMInstall(myNMPtr);
  713. }
  714.  
  715. /**************************************
  716. *    Notification response procedure. We don't do anything
  717. */
  718.  
  719. static pascal void NotifyResponse(NMRec *myNMPtr)
  720. {
  721. }
  722.  
  723. /**************************************
  724. *    Removal of notification record from system queue
  725. */
  726.  
  727. static void RemoveNotification(NMRec *myNMPtr)
  728. {
  729.     NMRemove(myNMPtr);
  730. }
  731.  
  732.